#!/bin/sh
# 10 Feb 2010 by shinobar (Masaki Shinomiya <shino@pos.to>)
#-
# (GUI) xkbconfigmanager sets X keyboard layout and /etc/keymap
# which may be an invalid console keymap (it doesn't matter)
#
# (pkeys BOOT PARAM, STARTUP & CLI) keymap-set asks xkbconfigmanager to apply
# a certain xkb layout based on the keymap provided in the boot param|command line|/etc/keymap
# ... and it can be rejected or applied in case it's a valid xkb layout
#     (it can also be an invalid console keymap.. it doesn't matter)
#
# (GUI) keymap-set execs chooselayot (xkbconfigmanager)
#-
# 12 Aug 2010 azerty(fr) fixed
#120627 handle different path to keymaps in kbd pkg.

keymap_country() {
	case $1 in
		us*) ACNTRY="(USA)";;
		fr*) ACNTRY="(France)";;
		it*) ACNTRY="(Italy)";;
		ba*) ACNTRY="(Bashkir)";;
		be*) ACNTRY="(Belgium)";;
		bg*) ACNTRY="(Bulgaria)";;
		br*) ACNTRY="(Brazil)";;
		by*) ACNTRY="(Byelorussian)";;
		cf*) ACNTRY="(French-Canadian)";;
		croat*) ACNTRY="(Croatia)";;
		cz*) ACNTRY="(Czech)";;
		de) ACNTRY="(Germany)";;
		de_*) ACNTRY="(Germany)";;
		de-*) ACNTRY="(Germany)";;
		dk*) ACNTRY="(Denmark)";;
		es*) ACNTRY="(Spain)";;
		fi*) ACNTRY="(Finland)";;
		hu*) ACNTRY="(Hungary)";;
		ka*) ACNTRY="(Kazakhstan)";;
		ky*) ACNTRY="(Kyrgyzstan)";;
		et*) ACNTRY="(Estonia)"   ;; ## WARNING: 'et' xkb = Amharic (Ethiopia)
		lt*) ACNTRY="(Lithuania)";;
		mk*) ACNTRY="(Macedonia)";;
		sr*) ACNTRY="(Serbia)";;
		tr*) ACNTRY="(Turkey)";;
		tt*) ACNTRY="(Tatar)";;
		sg*) ACNTRY="(Sango)";;
		ua*) ACNTRY="(Ukraine)";;
		gr*) ACNTRY="(Greece)";;
		il*) ACNTRY="(Israel)";;
		is*) ACNTRY="(Iceland)";;
		jp*) ACNTRY="(Japan)";;
		pc*) ACNTRY="(Japanese/English)";;
		la*) ACNTRY="(Latin_America)";;
		nl*) ACNTRY="(Netherlands)";;
		no*) ACNTRY="(Norway)";;
		pl*) ACNTRY="(Poland)";;
		pt*) ACNTRY="(Portugal)";;
		ro*) ACNTRY="(Romania)";;
		ru*) ACNTRY="(Russia)";;
		se*) ACNTRY="(Sweden)";;
		sv*) ACNTRY="(Sweden)";;
		sk*) ACNTRY="(Slovakia)";;
		sl*) ACNTRY="(Slovenia)";;
		uk*) ACNTRY="(UK)";;
		wangbe*) ACNTRY="(Belgium)";;
		azerty) ACNTRY="(Tandon)";;
		dvorak-r) ACNTRY="(Right_single-handed)";;
		dvorak-l) ACNTRY="(Left_single-handed)";;
		*)  ACNTRY="-";;
	esac
	echo $ACNTRY
}

usage() {
	MYNAME=$(basename $0)
	echo "
usage: $MYNAME [ somekeymap ]
		set keymap to 'somekeymap'
	$MYNAME cli
		ask keymap with console dialog
	$MYNAME --load
	    set keymap according to /etc/keymap
	$MYNAME --list
		show available key maps"
	exit 1
}

makelist() {
    DEFMAP="us"
    MAPS=$(echo "$MAPS"| grep -v "^$OLDMAP\$"| grep -v "^$DEFMAP"| sed -e 's/\.map//')
    OLDMAP=$(basename $OLDMAP .map)
    [ "$OLDMAP" = "$DEFMAP" ] && DEFMAP=""
    for MP in $OLDMAP $DEFMAP $MAPS; do
        ACNTRY=$(keymap_country $MP)
        echo "$MP $ACNTRY"
    done
}

#=============================================================

[ $# -le 2 ] || usage
LANG=C

. /etc/DISTRO_SPECS

KMAPPATH='/lib/keymaps'
[ -d /usr/share/kbd/keymaps/i386 ] && KMAPPATH='/usr/share/kbd/keymaps/i386'
[ -d /usr/share/keymaps/i386 ] && KMAPPATH='/usr/share/keymaps/i386' #debian, gentoo. note, debian files have extension .kmap.gz, gentoo have .map.gz
case $KMAPPATH in #120627
	/lib/keymaps) KMAPFILES="`find /lib/keymaps -mindepth 1 -maxdepth 1 -name '*.gz' | sort`" ;; #ex: us.gz
	*) KMAPFILES="`find ${KMAPPATH}/[^i]* -name '*.map' -o -name '*.kmap' -o -name '*.map.gz' -o -name '*.kmap.gz' -not -name 'defkeymap*' | sort`" ;;
esac
MAPS="$(echo "$KMAPFILES" | sed -e 's%^.*/%%' -e 's%\.gz$%%')"

OLDMAP=""
[ -f /etc/keymap ] && OLDMAP=$(cat /etc/keymap)
[ "$OLDMAP" = "" ] && OLDMAP="us"
[ "$DISPLAY" ] && XSTATUS="yes" || XSTATUS=""

#=============================================================

# options
NEWMAP=""
for i in $@
do
	case "$1" in
		*-li*) # show available key maps
			makelist
			exit ;;
		*-lo*) # load keymap according /etc/keymap
			NEWMAP=$(cat /etc/keymap 2>/dev/null)
			[ -z "$NEWMAP" ] && exit 1
			;;
		--startup)
			KEXT=''
			[ -f ${KMAPPATH}/qwerty/us.map ] && KEXT='.map'
			[ -f ${KMAPPATH}/qwerty/us.map.gz ] && KEXT='.map'
			[ -f ${KMAPPATH}/qwerty/us.kmap ] && KEXT='.kmap'
			[ -f ${KMAPPATH}/qwerty/us.kmap.gz ] && KEXT='.kmap'
			[ ! -f /etc/keymap ] && echo -n "us${KEXT}" > /etc/keymap
			[ ! -f /etc/codepage ] && echo -n "" > /etc/codepage
			;;
		cli|*-cli) XSTATUS="" ;;
		-*) usage ;;
		*)
			NEWMAP="$(echo "$MAPS" | grep "^${1}$" | head -1)"
			NEWMAP2="$(echo "$MAPS" | grep "^${1}" | head -1)"
			if [ "$NEWMAP" ] ; then
				echo "$NEWMAP" > /etc/keymap
			elif [ "$NEWMAP2" ] ; then
				NEWMAP=$NEWMAP2
				echo "$NEWMAP" > /etc/keymap
			else
				echo "keymap-set: ${1}: keymap not found"
				INVALID_KEYMAP=1
			fi
			break
			;;
	esac
	shift
done
[ $# -le 1 ] || usage

#=============================================================

# verify
if [ "$NEWMAP" = "" ] ; then
	NEWMAP=$(basename "$1" .gz)
fi

if [ "$NEWMAP" = "" ] ; then
	DIALOG="dialog --aspect 10"
	MENUOPT="--menu"
	REP=/tmp/$(basename $0).txt
	if [ "$XSTATUS" = "yes" ] ; then
		#MENUOPT="--menubox"
		exec chooselayout
	fi
	CHOICES=$(makelist)
	CHOICES=$(echo $CHOICES|sed -e "s/(/'(/g" -e "s/)/)'/g")
	eval "$DIALOG --title \"$(gettext 'Set console keyboard layout')\"  $MENUOPT \"$(gettext 'Choose keyboard layout for your country...')\" 0 0 0 $CHOICES" 2>$REP #111020 typo.
	NEWMAP=$(tail -n 1 $REP)
	rm -f $REP
else
	XKBLAYOUT=${NEWMAP}
	# --
	# https://kernel.googlesource.com/pub/scm/linux/kernel/git/legion/kbd/+/d20fdc07df621f6104592573b53c209976991978/data/keymaps/i386/qwerty
	# https://wiki.archlinux.org/index.php/KEYMAP_(Português)
	# --
	# keymaps in /lib/keymaps
	case "$XKBLAYOUT" in
		azerty)    XKBLAYOUT="fr"  ;; #azerty
		be*)       XKBLAYOUT="be"  ;; #belgium - be-latin1
		br*)       XKBLAYOUT="br"  ;; #brazil  - br-abnt, br-abnt2, br-latin1-abnt2, br-latin1-us
		#by)       XKBLAYOUT="by"  ;; #belarus
		cf*)       XKBLAYOUT="ca"  ;; #canadian french
		croat)     XKBLAYOUT="hr"  ;; #croat
		#cz)       XKBLAYOUT="cz"  ;; #czech
		de*)       XKBLAYOUT="de"  ;; #german  - de, de-latin1
		#dk)       XKBLAYOUT="dk"  ;; #danish
		dvorak)    XKBLAYOUT="us"  ;; #dvorak
		#dvorak-l) XKBLAYOUT=""    ;; ??
		#dvorak-r) XKBLAYOUT=""    ;; ??
		#es)       XKBLAYOUT="es"  ;; #spanish
		et*)       XKBLAYOUT="ee"  ;; #estonian - WARNING: 'et' xkb = Amharic (Ethiopia)
		#fi)       XKBLAYOUT="fi"  ;; #finland
		#fr)       XKBLAYOUT="fr"  ;; #french
		#gr)       XKBLAYOUT="gr"  ;; #greek
		hu*)       XKBLAYOUT="hu"  ;; #hungarian - hu, hu101
		#il)       XKBLAYOUT="il"  ;; #hebrew
		#it)       XKBLAYOUT="it"  ;; #italian
		jp*)       XKBLAYOUT="jp"  ;; #japanese   - jp106
		#lt)       XKBLAYOUT="lt"  ;; #lithuanian
		#mk)       XKBLAYOUT="mk"  ;; #macedonian
		#nl)       XKBLAYOUT="nl"  ;; #dutch
		#no)       XKBLAYOUT="no"  ;; #norwegian
		#pl)       XKBLAYOUT="pl"  ;; #polish
		pt*)       XKBLAYOUT="pt"  ;; #portuguese  - pt-latin1
		#ro)       XKBLAYOUT="ro"  ;; #romanian
		#ru)       XKBLAYOUT="ru"  ;; #russian
		#se)       XKBLAYOUT="se"  ;; #swedish
		#sg)       XKBLAYOUT=""    ;; ??? singapore (malay?? -> 'my' -> 'in' xkb)
		sk*)       XKBLAYOUT="sk"  ;; #slovak - sk-qwerty, sk-qwertz
		slovene)   XKBLAYOUT="si"  ;; #slovene
		sv-latin1) XKBLAYOUT="se"  ;; #sweden
		uk*)       XKBLAYOUT="gb"  ;; #united kingdom
		#us)       XKBLAYOUT="us"  ;; #english
		wangbe)    XKBLAYOUT="be"  ;; #belgium
	esac
	xkbconfigmanager setlayout ${XKBLAYOUT}
	XKBCONFIG=1
	if [ $INVALID_KEYMAP ] ; then
		exit
	fi
fi

NEW=$(echo "$MAPS"|grep "^${NEWMAP}$"| head -n 1) #120715 wrong, fix.
if [ "$NEW" = "" ];then
	NEWMAP=$(echo $NEWMAP| cut -b 1-2)
	NEW=$(echo "$MAPS"|grep -w "^$NEWMAP"| head -n 1)
fi

# update
if [ "$NEW" != "" ];then
	NEWMAP=$NEW
	if [ ! "$XKBCONFIG" ] ; then
		xkbconfigmanager -q setlayout ${NEW}
	fi
	echo -n $NEWMAP > /etc/keymap
	case $NEWMAP in
		*.map|*.kmap)
			echo loadkeys $NEWMAP
			loadkeys $NEWMAP || exit 1 #120627
			echo "'${NEWMAP}' keymap loaded"
			;;
		*)
			gzip -dcf /lib/keymaps/$NEWMAP.gz | loadkmap || exit 1
			echo "/lib/keymaps/${NEWMAP}.gz loaded"
			;;
	esac
fi

[ "$NEW" != "" ] && NEWMAP=$NEW || exit 1
echo -n $NEWMAP > /etc/keymap

### END ###
